// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
//
// ███╗   ██╗ ██████╗ ████████╗██╗ ██████╗███████╗
// ████╗  ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝
// ██╔██╗ ██║██║   ██║   ██║   ██║██║     █████╗
// ██║╚██╗██║██║   ██║   ██║   ██║██║     ██╔══╝
// ██║ ╚████║╚██████╔╝   ██║   ██║╚██████╗███████╗
// ╚═╝  ╚═══╝ ╚═════╝    ╚═╝   ╚═╝ ╚═════╝╚══════╝
// ------------------------------------------------
//
// This file is automatically generated.
// Please do not edit these files manually.
//
// ------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text.Json;
using System.Text.Json.Serialization;

#nullable restore
namespace Elastic.Clients.Elasticsearch.Ml
{
	public sealed partial class Detector
	{
		[JsonInclude]
		[JsonPropertyName("by_field_name")]
		public Elastic.Clients.Elasticsearch.Field? ByFieldName { get; set; }

		[JsonInclude]
		[JsonPropertyName("custom_rules")]
		public IEnumerable<Elastic.Clients.Elasticsearch.Ml.DetectionRule>? CustomRules { get; set; }

		[JsonInclude]
		[JsonPropertyName("detector_description")]
		public string? DetectorDescription { get; set; }

		[JsonInclude]
		[JsonPropertyName("detector_index")]
		public int? DetectorIndex { get; set; }

		[JsonInclude]
		[JsonPropertyName("exclude_frequent")]
		public Elastic.Clients.Elasticsearch.Ml.ExcludeFrequent? ExcludeFrequent { get; set; }

		[JsonInclude]
		[JsonPropertyName("field_name")]
		public Elastic.Clients.Elasticsearch.Field? FieldName { get; set; }

		[JsonInclude]
		[JsonPropertyName("function")]
		public string Function { get; set; }

		[JsonInclude]
		[JsonPropertyName("over_field_name")]
		public Elastic.Clients.Elasticsearch.Field? OverFieldName { get; set; }

		[JsonInclude]
		[JsonPropertyName("partition_field_name")]
		public Elastic.Clients.Elasticsearch.Field? PartitionFieldName { get; set; }

		[JsonInclude]
		[JsonPropertyName("use_null")]
		public bool? UseNull { get; set; }
	}

	public sealed partial class DetectorDescriptor<TDocument> : SerializableDescriptorBase<DetectorDescriptor<TDocument>>
	{
		internal DetectorDescriptor(Action<DetectorDescriptor<TDocument>> configure) => configure.Invoke(this);
		public DetectorDescriptor() : base()
		{
		}

		private Elastic.Clients.Elasticsearch.Field? ByFieldNameValue { get; set; }

		private IEnumerable<Elastic.Clients.Elasticsearch.Ml.DetectionRule>? CustomRulesValue { get; set; }

		private DetectionRuleDescriptor CustomRulesDescriptor { get; set; }

		private Action<DetectionRuleDescriptor> CustomRulesDescriptorAction { get; set; }

		private Action<DetectionRuleDescriptor>[] CustomRulesDescriptorActions { get; set; }

		private string? DetectorDescriptionValue { get; set; }

		private int? DetectorIndexValue { get; set; }

		private Elastic.Clients.Elasticsearch.Ml.ExcludeFrequent? ExcludeFrequentValue { get; set; }

		private Elastic.Clients.Elasticsearch.Field? FieldNameValue { get; set; }

		private string FunctionValue { get; set; }

		private Elastic.Clients.Elasticsearch.Field? OverFieldNameValue { get; set; }

		private Elastic.Clients.Elasticsearch.Field? PartitionFieldNameValue { get; set; }

		private bool? UseNullValue { get; set; }

		public DetectorDescriptor<TDocument> ByFieldName(Elastic.Clients.Elasticsearch.Field? byFieldName)
		{
			ByFieldNameValue = byFieldName;
			return Self;
		}

		public DetectorDescriptor<TDocument> ByFieldName<TValue>(Expression<Func<TDocument, TValue>> byFieldName)
		{
			ByFieldNameValue = byFieldName;
			return Self;
		}

		public DetectorDescriptor<TDocument> CustomRules(IEnumerable<Elastic.Clients.Elasticsearch.Ml.DetectionRule>? customRules)
		{
			CustomRulesDescriptor = null;
			CustomRulesDescriptorAction = null;
			CustomRulesDescriptorActions = null;
			CustomRulesValue = customRules;
			return Self;
		}

		public DetectorDescriptor<TDocument> CustomRules(DetectionRuleDescriptor descriptor)
		{
			CustomRulesValue = null;
			CustomRulesDescriptorAction = null;
			CustomRulesDescriptorActions = null;
			CustomRulesDescriptor = descriptor;
			return Self;
		}

		public DetectorDescriptor<TDocument> CustomRules(Action<DetectionRuleDescriptor> configure)
		{
			CustomRulesValue = null;
			CustomRulesDescriptor = null;
			CustomRulesDescriptorActions = null;
			CustomRulesDescriptorAction = configure;
			return Self;
		}

		public DetectorDescriptor<TDocument> CustomRules(params Action<DetectionRuleDescriptor>[] configure)
		{
			CustomRulesValue = null;
			CustomRulesDescriptor = null;
			CustomRulesDescriptorAction = null;
			CustomRulesDescriptorActions = configure;
			return Self;
		}

		public DetectorDescriptor<TDocument> DetectorDescription(string? detectorDescription)
		{
			DetectorDescriptionValue = detectorDescription;
			return Self;
		}

		public DetectorDescriptor<TDocument> DetectorIndex(int? detectorIndex)
		{
			DetectorIndexValue = detectorIndex;
			return Self;
		}

		public DetectorDescriptor<TDocument> ExcludeFrequent(Elastic.Clients.Elasticsearch.Ml.ExcludeFrequent? excludeFrequent)
		{
			ExcludeFrequentValue = excludeFrequent;
			return Self;
		}

		public DetectorDescriptor<TDocument> FieldName(Elastic.Clients.Elasticsearch.Field? fieldName)
		{
			FieldNameValue = fieldName;
			return Self;
		}

		public DetectorDescriptor<TDocument> FieldName<TValue>(Expression<Func<TDocument, TValue>> fieldName)
		{
			FieldNameValue = fieldName;
			return Self;
		}

		public DetectorDescriptor<TDocument> Function(string function)
		{
			FunctionValue = function;
			return Self;
		}

		public DetectorDescriptor<TDocument> OverFieldName(Elastic.Clients.Elasticsearch.Field? overFieldName)
		{
			OverFieldNameValue = overFieldName;
			return Self;
		}

		public DetectorDescriptor<TDocument> OverFieldName<TValue>(Expression<Func<TDocument, TValue>> overFieldName)
		{
			OverFieldNameValue = overFieldName;
			return Self;
		}

		public DetectorDescriptor<TDocument> PartitionFieldName(Elastic.Clients.Elasticsearch.Field? partitionFieldName)
		{
			PartitionFieldNameValue = partitionFieldName;
			return Self;
		}

		public DetectorDescriptor<TDocument> PartitionFieldName<TValue>(Expression<Func<TDocument, TValue>> partitionFieldName)
		{
			PartitionFieldNameValue = partitionFieldName;
			return Self;
		}

		public DetectorDescriptor<TDocument> UseNull(bool? useNull = true)
		{
			UseNullValue = useNull;
			return Self;
		}

		protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
		{
			writer.WriteStartObject();
			if (ByFieldNameValue is not null)
			{
				writer.WritePropertyName("by_field_name");
				JsonSerializer.Serialize(writer, ByFieldNameValue, options);
			}

			if (CustomRulesDescriptor is not null)
			{
				writer.WritePropertyName("custom_rules");
				writer.WriteStartArray();
				JsonSerializer.Serialize(writer, CustomRulesDescriptor, options);
				writer.WriteEndArray();
			}
			else if (CustomRulesDescriptorAction is not null)
			{
				writer.WritePropertyName("custom_rules");
				writer.WriteStartArray();
				JsonSerializer.Serialize(writer, new DetectionRuleDescriptor(CustomRulesDescriptorAction), options);
				writer.WriteEndArray();
			}
			else if (CustomRulesDescriptorActions is not null)
			{
				writer.WritePropertyName("custom_rules");
				writer.WriteStartArray();
				foreach (var action in CustomRulesDescriptorActions)
				{
					JsonSerializer.Serialize(writer, new DetectionRuleDescriptor(action), options);
				}

				writer.WriteEndArray();
			}
			else if (CustomRulesValue is not null)
			{
				writer.WritePropertyName("custom_rules");
				JsonSerializer.Serialize(writer, CustomRulesValue, options);
			}

			if (!string.IsNullOrEmpty(DetectorDescriptionValue))
			{
				writer.WritePropertyName("detector_description");
				writer.WriteStringValue(DetectorDescriptionValue);
			}

			if (DetectorIndexValue.HasValue)
			{
				writer.WritePropertyName("detector_index");
				writer.WriteNumberValue(DetectorIndexValue.Value);
			}

			if (ExcludeFrequentValue is not null)
			{
				writer.WritePropertyName("exclude_frequent");
				JsonSerializer.Serialize(writer, ExcludeFrequentValue, options);
			}

			if (FieldNameValue is not null)
			{
				writer.WritePropertyName("field_name");
				JsonSerializer.Serialize(writer, FieldNameValue, options);
			}

			writer.WritePropertyName("function");
			writer.WriteStringValue(FunctionValue);
			if (OverFieldNameValue is not null)
			{
				writer.WritePropertyName("over_field_name");
				JsonSerializer.Serialize(writer, OverFieldNameValue, options);
			}

			if (PartitionFieldNameValue is not null)
			{
				writer.WritePropertyName("partition_field_name");
				JsonSerializer.Serialize(writer, PartitionFieldNameValue, options);
			}

			if (UseNullValue.HasValue)
			{
				writer.WritePropertyName("use_null");
				writer.WriteBooleanValue(UseNullValue.Value);
			}

			writer.WriteEndObject();
		}
	}

	public sealed partial class DetectorDescriptor : SerializableDescriptorBase<DetectorDescriptor>
	{
		internal DetectorDescriptor(Action<DetectorDescriptor> configure) => configure.Invoke(this);
		public DetectorDescriptor() : base()
		{
		}

		private Elastic.Clients.Elasticsearch.Field? ByFieldNameValue { get; set; }

		private IEnumerable<Elastic.Clients.Elasticsearch.Ml.DetectionRule>? CustomRulesValue { get; set; }

		private DetectionRuleDescriptor CustomRulesDescriptor { get; set; }

		private Action<DetectionRuleDescriptor> CustomRulesDescriptorAction { get; set; }

		private Action<DetectionRuleDescriptor>[] CustomRulesDescriptorActions { get; set; }

		private string? DetectorDescriptionValue { get; set; }

		private int? DetectorIndexValue { get; set; }

		private Elastic.Clients.Elasticsearch.Ml.ExcludeFrequent? ExcludeFrequentValue { get; set; }

		private Elastic.Clients.Elasticsearch.Field? FieldNameValue { get; set; }

		private string FunctionValue { get; set; }

		private Elastic.Clients.Elasticsearch.Field? OverFieldNameValue { get; set; }

		private Elastic.Clients.Elasticsearch.Field? PartitionFieldNameValue { get; set; }

		private bool? UseNullValue { get; set; }

		public DetectorDescriptor ByFieldName(Elastic.Clients.Elasticsearch.Field? byFieldName)
		{
			ByFieldNameValue = byFieldName;
			return Self;
		}

		public DetectorDescriptor ByFieldName<TDocument, TValue>(Expression<Func<TDocument, TValue>> byFieldName)
		{
			ByFieldNameValue = byFieldName;
			return Self;
		}

		public DetectorDescriptor ByFieldName<TDocument>(Expression<Func<TDocument, object>> byFieldName)
		{
			ByFieldNameValue = byFieldName;
			return Self;
		}

		public DetectorDescriptor CustomRules(IEnumerable<Elastic.Clients.Elasticsearch.Ml.DetectionRule>? customRules)
		{
			CustomRulesDescriptor = null;
			CustomRulesDescriptorAction = null;
			CustomRulesDescriptorActions = null;
			CustomRulesValue = customRules;
			return Self;
		}

		public DetectorDescriptor CustomRules(DetectionRuleDescriptor descriptor)
		{
			CustomRulesValue = null;
			CustomRulesDescriptorAction = null;
			CustomRulesDescriptorActions = null;
			CustomRulesDescriptor = descriptor;
			return Self;
		}

		public DetectorDescriptor CustomRules(Action<DetectionRuleDescriptor> configure)
		{
			CustomRulesValue = null;
			CustomRulesDescriptor = null;
			CustomRulesDescriptorActions = null;
			CustomRulesDescriptorAction = configure;
			return Self;
		}

		public DetectorDescriptor CustomRules(params Action<DetectionRuleDescriptor>[] configure)
		{
			CustomRulesValue = null;
			CustomRulesDescriptor = null;
			CustomRulesDescriptorAction = null;
			CustomRulesDescriptorActions = configure;
			return Self;
		}

		public DetectorDescriptor DetectorDescription(string? detectorDescription)
		{
			DetectorDescriptionValue = detectorDescription;
			return Self;
		}

		public DetectorDescriptor DetectorIndex(int? detectorIndex)
		{
			DetectorIndexValue = detectorIndex;
			return Self;
		}

		public DetectorDescriptor ExcludeFrequent(Elastic.Clients.Elasticsearch.Ml.ExcludeFrequent? excludeFrequent)
		{
			ExcludeFrequentValue = excludeFrequent;
			return Self;
		}

		public DetectorDescriptor FieldName(Elastic.Clients.Elasticsearch.Field? fieldName)
		{
			FieldNameValue = fieldName;
			return Self;
		}

		public DetectorDescriptor FieldName<TDocument, TValue>(Expression<Func<TDocument, TValue>> fieldName)
		{
			FieldNameValue = fieldName;
			return Self;
		}

		public DetectorDescriptor FieldName<TDocument>(Expression<Func<TDocument, object>> fieldName)
		{
			FieldNameValue = fieldName;
			return Self;
		}

		public DetectorDescriptor Function(string function)
		{
			FunctionValue = function;
			return Self;
		}

		public DetectorDescriptor OverFieldName(Elastic.Clients.Elasticsearch.Field? overFieldName)
		{
			OverFieldNameValue = overFieldName;
			return Self;
		}

		public DetectorDescriptor OverFieldName<TDocument, TValue>(Expression<Func<TDocument, TValue>> overFieldName)
		{
			OverFieldNameValue = overFieldName;
			return Self;
		}

		public DetectorDescriptor OverFieldName<TDocument>(Expression<Func<TDocument, object>> overFieldName)
		{
			OverFieldNameValue = overFieldName;
			return Self;
		}

		public DetectorDescriptor PartitionFieldName(Elastic.Clients.Elasticsearch.Field? partitionFieldName)
		{
			PartitionFieldNameValue = partitionFieldName;
			return Self;
		}

		public DetectorDescriptor PartitionFieldName<TDocument, TValue>(Expression<Func<TDocument, TValue>> partitionFieldName)
		{
			PartitionFieldNameValue = partitionFieldName;
			return Self;
		}

		public DetectorDescriptor PartitionFieldName<TDocument>(Expression<Func<TDocument, object>> partitionFieldName)
		{
			PartitionFieldNameValue = partitionFieldName;
			return Self;
		}

		public DetectorDescriptor UseNull(bool? useNull = true)
		{
			UseNullValue = useNull;
			return Self;
		}

		protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
		{
			writer.WriteStartObject();
			if (ByFieldNameValue is not null)
			{
				writer.WritePropertyName("by_field_name");
				JsonSerializer.Serialize(writer, ByFieldNameValue, options);
			}

			if (CustomRulesDescriptor is not null)
			{
				writer.WritePropertyName("custom_rules");
				writer.WriteStartArray();
				JsonSerializer.Serialize(writer, CustomRulesDescriptor, options);
				writer.WriteEndArray();
			}
			else if (CustomRulesDescriptorAction is not null)
			{
				writer.WritePropertyName("custom_rules");
				writer.WriteStartArray();
				JsonSerializer.Serialize(writer, new DetectionRuleDescriptor(CustomRulesDescriptorAction), options);
				writer.WriteEndArray();
			}
			else if (CustomRulesDescriptorActions is not null)
			{
				writer.WritePropertyName("custom_rules");
				writer.WriteStartArray();
				foreach (var action in CustomRulesDescriptorActions)
				{
					JsonSerializer.Serialize(writer, new DetectionRuleDescriptor(action), options);
				}

				writer.WriteEndArray();
			}
			else if (CustomRulesValue is not null)
			{
				writer.WritePropertyName("custom_rules");
				JsonSerializer.Serialize(writer, CustomRulesValue, options);
			}

			if (!string.IsNullOrEmpty(DetectorDescriptionValue))
			{
				writer.WritePropertyName("detector_description");
				writer.WriteStringValue(DetectorDescriptionValue);
			}

			if (DetectorIndexValue.HasValue)
			{
				writer.WritePropertyName("detector_index");
				writer.WriteNumberValue(DetectorIndexValue.Value);
			}

			if (ExcludeFrequentValue is not null)
			{
				writer.WritePropertyName("exclude_frequent");
				JsonSerializer.Serialize(writer, ExcludeFrequentValue, options);
			}

			if (FieldNameValue is not null)
			{
				writer.WritePropertyName("field_name");
				JsonSerializer.Serialize(writer, FieldNameValue, options);
			}

			writer.WritePropertyName("function");
			writer.WriteStringValue(FunctionValue);
			if (OverFieldNameValue is not null)
			{
				writer.WritePropertyName("over_field_name");
				JsonSerializer.Serialize(writer, OverFieldNameValue, options);
			}

			if (PartitionFieldNameValue is not null)
			{
				writer.WritePropertyName("partition_field_name");
				JsonSerializer.Serialize(writer, PartitionFieldNameValue, options);
			}

			if (UseNullValue.HasValue)
			{
				writer.WritePropertyName("use_null");
				writer.WriteBooleanValue(UseNullValue.Value);
			}

			writer.WriteEndObject();
		}
	}
}